﻿using System;
using Microsoft.VisualStudio.Shell.Interop;

namespace VsxTools.OutputWindow
{
    public sealed class OutputWindowPane
    {
        private readonly OutputPaneDefinition _paneDefinition;
        private readonly IVsOutputWindowPane _pane;
        private string _name;

        internal OutputWindowPane(OutputPaneDefinition definition, IVsOutputWindowPane pane)
        {
            _paneDefinition = definition;
            ThreadSafe = definition.ThreadSafe;
            _name = definition.Name;
            _pane = pane;
        }

        public bool ThreadSafe { get; set; }

        public string Name
        {
            get
            {
                if (IsVirtual) return _name;
                string name = string.Empty;
                _pane.GetName(ref name);
                return name;
            }
            set
            {
                if (IsVirtual) _name = value;
                else _pane.SetName(value);
            }
        }

        public bool IsVirtual
        {
            get { return _paneDefinition == null || _paneDefinition.IsSilent || _pane == null; }
        }

        public void Activate()
        {
            if (IsVirtual) return;
            _pane.Activate();
        }

        public void Hide()
        {
            if (IsVirtual) return;
            _pane.Hide();
        }

        public void Clear()
        {
            if (IsVirtual) return;
            _pane.Clear();
        }

        public void Write(string output)
        {
            OutputString(output);
        }

        public void Write(string format, params object[] parameters)
        {
            OutputString(string.Format(format, parameters));
        }

        public void Write(IFormatProvider provider, string format, params object[] parameters)
        {
            OutputString(string.Format(provider, format, parameters));
        }

        public void WriteLine(string output)
        {
            OutputString(output + Environment.NewLine);
        }

        public void WriteLine(string format, params object[] parameters)
        {
            OutputString(string.Format(format + Environment.NewLine, parameters));
        }

        public void WriteLine(IFormatProvider provider, string format, params object[] parameters)
        {
            OutputString(string.Format(provider, format + Environment.NewLine, parameters));
        }

        private void OutputString(string output)
        {
            if (IsVirtual) return;
            if (_paneDefinition.ThreadSafe) _pane.OutputStringThreadSafe(output);
            else _pane.OutputString(output);
        }
    }
}
